(function(root, factory) {
	if(typeof define === 'function' && define.amd) {
		// AMD. Register as an anonymous module.
		define(['exports', 'vue'], factory);
	} else if(typeof exports === 'object' && typeof exports.nodeName !== 'string') {
		// CommonJS
		factory(exports, require('vue'));
	} else {
		// Browser globals
		factory(({}), root.Vue);
	}
}(this, function(exports, Vue) {
	Vue.lazyimg = {
		install: function(Vue, options) {
			//custom scrollEnd event, calc scroll speed, over specified speed value then won't load the img src
//			if (options.speed) {
//				var cntr = 0;
//				var lastCntr = 0;
//				var diff = 0;
//				var scrollEnd = document.createEvent('HTMLEvents');
//				scrollEnd.initEvent('scrollEnd');
//				scrollEnd.eventType = 'message';
//
//				function enterFrame() {
//					if (cntr != lastCntr) {
//						diff++;
//						if (diff == 5) {
//							window.dispatchEvent(scrollEnd);
//							cntr = lastCntr;
//						}
//					}
//					requestAnimationFrame(enterFrame);
//				}
//				window.requestAnimationFrame(enterFrame);
//				document.addEventListener('scroll', function() {
//					lastCntr = cntr;
//					diff = 0;
//					cntr++;
//				}, true);
//			}
//			//compute scroll speed
//			var lastPosY = document.body ? document.body.getBoundingClientRect().top : document.head.parentNode.getBoundingClientRect().top;
//			var lastPosX = document.body ? document.body.getBoundingClientRect().left : document.head.parentNode.getBoundingClientRect().left;
//			var lastSpeeds = [];
//			var aveSpeed = 0;
//
//			function getSpeed(el) {
//				var curPosY = el ? el.getBoundingClientRect().top : 0;
//				var curPosX = el ? el.getBoundingClientRect().left : 0;
//				var speedY = lastPosY - curPosY;
//				var speedX = lastPosX - curPosX;
//				if (lastSpeeds.length < 10) {
//					lastSpeeds.push((speedY + speedX) / 2);
//				} else {
//					lastSpeeds.shift();
//					lastSpeeds.push((speedY + speedX) / 2);
//				}
//				var sumSpeed = 0;
//				lastSpeeds.forEach(function(speed) {
//					sumSpeed += speed;
//				})
//				aveSpeed = Math.abs(sumSpeed / lastSpeeds.length);
//				lastPosY = curPosY;
//				lastPosX = curPosX;
//			}
//			document.addEventListener('scroll', function(e) {
//				if (!options.speed) return;
//				var el = null;
//				for (var i = 0; i < e.target.childNodes.length; i++) {
//					if (e.target.childNodes[i].nodeType == 1) {
//						el = e.target.childNodes[i];
//						break;
//					}
//				}
//				getSpeed(el);
//			}, true);
			var imgLoaded = false;
			var definition = {
				update: function(value, oldValue) {
					if(imgLoaded) {
						this.el.src = value;
						return;
					}
					this.placeholderLoadFlag = false;
					this.srcLoadFlag = false;
					this.isNoFadeIn = this.modifiers.nofadein || options.nofadein;
					this.isNoHori = this.modifiers.nohori || options.nohori;
					if(!this.isNoFadeIn) {
						this.el.style.opacity = 0;
						this.el.style.transition = 'opacity .4s';
						this.el.style.webkitTransition = 'opacity .4s';
					}
					this.compute = function(value) {
						if(this.placeholderLoadFlag || this.srcLoadFlag) {
							var rect = this.el.getBoundingClientRect();
							var vpWidth = document.head.parentNode.clientWidth;
							var vpHeight = document.head.parentNode.clientHeight;
							var loadImg = function() {
								var self = this;
								this.el.src = value;
								imgLoaded = true;
								this.elSecondLoadEvent = frameScript.addEventListener(this.el, "load", this.onloadEnd);
								this.windowScrollEvent();
								this.windowResizeEvent();
								//this.windowScrollEvent();
								//lastSpeeds = [];
							}.bind(this);
							if(this.el.src == value) return;
							if(this.isNoHori) {
								if(rect.bottom >= 0 && rect.top <= vpHeight) {
									loadImg();
								}
								
							} else if(rect.bottom >= 0 && rect.top <= vpHeight && rect.right >= 0 && rect.left <= vpWidth) {
								loadImg();
							}
						}
					}.bind(this, value);
					/*this.computeBySpeed = function() {
						if (options.speed && aveSpeed > options.speed) {
							return;
						}
						this.compute();
					}.bind(this);*/
					this.onload = function() {
						this.elFirstLoadEvent();
//						this.windowScrollEndEvent = frameScript.addEventListener(window, "scrollEnd", this.compute, true);
//						this.windowScrollEvent = frameScript.addEventListener(window, "scroll", this.computeBySpeed, true);*/
						this.windowScrollEvent = frameScript.addEventListener(window, "scroll", this.compute, true);
						this.windowResizeEvent = frameScript.addEventListener(window, "resize", this.compute, true);
						this.placeholderLoadFlag = true;
						this.compute();
					}.bind(this);
					this.onloadEnd = function() {

						if(!this.isNoFadeIn) {
							this.el.style.opacity = 1;
						}
						this.elSecondLoadEvent();
					}.bind(this);
					this.elFirstLoadEvent = frameScript.addEventListener(this.el, "load", this.onload);
				},
				unbind: function() {
					if(this.elFirstLoadEvent){
						this.elFirstLoadEvent();
					}
					if(this.elSecondLoadEvent) {
						this.elSecondLoadEvent();
					}
					if(this.windowResizeEvent) {
						this.windowResizeEvent();
					}
					if(this.windowScrollEvent) {
						this.windowScrollEvent();
					}
				},
			}

			Vue.directive('lazyload', definition);
		}
	}
}));